package com.fifth.apartment.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.aliyuncs.exceptions.ClientException;
import com.fifth.apartment.config.LoginUser;
import com.fifth.apartment.config.SmsCodeAuthenticationToken;
import com.fifth.apartment.config.SpringSecurityDetailsService;
import com.fifth.apartment.constant.MessageConstant;
import com.fifth.apartment.constant.RedisMessageConstant;
import com.fifth.apartment.entity.User;
import com.fifth.apartment.exception.CustomException;
import com.fifth.apartment.result.Result;
import com.fifth.apartment.service.UserService;
import com.fifth.apartment.utils.JwtHelper;
import com.fifth.apartment.utils.SMSUtils;
import com.fifth.apartment.utils.ValidateCodeUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpRequest;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static org.springframework.security.web.context.HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY;

/**
 * TODO
 *
 * @author Dao
 * @since 2024/7/2
 */
@RestController
@RequestMapping("/admin/user")
@Api(tags = "用户接口 ")
@Slf4j
public class UserController {

    @Autowired
    private UserService service;
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private SpringSecurityDetailsService securityDetailsService;


    //获得登录账号
    private  String loginAccount;

    @PostMapping ("login")
    @Operation(summary = "登录")
    public Result login(@RequestBody User user){
        log.info(""+user);

        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if (Objects.isNull(authenticate)){
            throw new CustomException("用户名或者密码错误");
        }
        //认证通过
        LoginUser principal = (LoginUser) authenticate.getPrincipal();
        //获取用户信息
        user = principal.getUser();
        Integer userId = user.getId();
        //将信息存入redis中
        String token = RedisMessageConstant.LONGIN_USER_TOKEN+"::"+ userId;
        //将对象转换为json字符串
        String jsonStr = JSONUtil.toJsonStr(user);
        redisTemplate.opsForValue().set(token,jsonStr);
        //生成token数据给前端
        String token1 = JwtHelper.createToken(userId, user.getUsername());
        HashMap<String, String> data = new HashMap<>();
        data.put("avatar","src\\assets\\user.jpg");
        data.put("username", user.getUsername());
        data.put("nickname", user.getName());
        data.put("accessToken",token1);
        data.put("roles","dhssfds");
        return new Result(true, MessageConstant.LOGIN_SUCCESS,data);
    }


//    public Result login(@RequestBody User user){
//        log.info("login,{}",user);
//        //User user = service.selectUserLogin();
//        user.setToken("12312312");
//        return Result.success(user);
//    }

    @GetMapping("getUserInfo")
    public Result getUserInfo(){
        log.info("getUserInfo,{}");
        User loginUser = service.selectAllUser(loginAccount);
        return Result.success(loginUser);
    }


    @PostMapping("/code")
    @Operation(summary = "验证码")
    public Result sendSmsCode(@RequestParam("phone") String phone, HttpServletRequest request){
        //1.判断验证码在一分钟内是否重复发送  redis存储一份 1分钟有效  判断redis中是否存在 则表示是否重复发送
        Object code = redisTemplate.opsForValue().get(phone + "_" + RedisMessageConstant.SENDTYPE_LOGIN);
        if (!Objects.isNull(code)) {
            return new Result(false, MessageConstant.SEND_PHONE_HAS);
        }
        try {
            //发送短信
            Integer integer = ValidateCodeUtils.generateValidateCode(4);
//            SMSUtils.sendMessage(SMSUtils.VALIDATE_CODE,phone,integer.toString());
            //将短信存储到redis中
            redisTemplate.opsForValue().set(
                    phone + "_" + RedisMessageConstant.SENDTYPE_LOGIN + "_" + integer,
                    integer.toString(),
                    5, TimeUnit.MINUTES
            );

            //再存储一个手机号，用于判断是否在一分钟内重复发送
            redisTemplate.opsForValue().set(
                    phone+ "_" + RedisMessageConstant.SENDTYPE_LOGIN,
                    integer.toString(),
                    1,TimeUnit.MINUTES
            );
            return new Result(true,MessageConstant.SEND_PHONE_SUCCESS,integer.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Result(false,MessageConstant.SEND_PHONE_FAIL);
    }

    @Operation(summary = "手机号登录")
    @PostMapping("/phone")
    public Result loginByPhoneAndCode(@RequestParam("phone")String phone, @RequestParam("smsCode")String smsCode, HttpServletRequest request) {
        if(StrUtil.isEmpty(phone)||StrUtil.isEmpty(smsCode)){
            return new Result(false,MessageConstant.USERLOGIN_LOGINVO_NOTNULL);
        }
        //1、校验用户输入的短信验证码是否正确，如果验证码错误则登录失败
        String result = (String) redisTemplate.opsForValue().get(
                phone + "_" + RedisMessageConstant.SENDTYPE_LOGIN + "_" + smsCode);
        if (Objects.isNull(result) || !smsCode.equals(result)) {
            return new Result(false,MessageConstant.USERLOGIN_VALIDATECODE_ERROR);
        }

        SmsCodeAuthenticationToken smsCodeAuthenticationToken = new SmsCodeAuthenticationToken(phone);
        Authentication authenticate = authenticationManager.authenticate(smsCodeAuthenticationToken);

        SecurityContext context = SecurityContextHolder.getContext();
        context.setAuthentication(authenticate);
        HttpSession session = request.getSession(true);
        //在session中存放security context,方便同一个session中控制用户的其他操作
        session.setAttribute(SPRING_SECURITY_CONTEXT_KEY, context);

        //将用户信息生成token给前端
        //认证通过
        LoginUser principal = (LoginUser) authenticate.getPrincipal();
        //获取用户信息
        User user = principal.getUser();
        String token1 = JwtHelper.createToken(user.getId(), user.getUsername());
        HashMap<String, String> data = new HashMap<>();
        data.put("avatar","src\\assets\\touxiang.jpg");
        data.put("username", user.getUsername());
        data.put("nickname", user.getName());
        data.put("accessToken",token1);
        data.put("roles","dhssfds");
        return new Result(true, MessageConstant.LOGIN_SUCCESS,data);
    }
}
